home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-08-28 | 5.8 KB | 307 lines | [TEXT/MPS ] |
- /*
- Fractal Popcorn - by John Jeppson.
-
- This source code is in the public domain.
- Written in MPW C.
-
- This program is an MPW Tool which implements Clifford A. Pickover's
- "Fractal Popcorn" as described in "Computer Recreations" by
- A.K.Dewdney in Scientific American, July 1989.
-
- From the MPW Worksheet execute:
-
- Popcorn top, left, edge
-
- where "top" and "left" are the corner of the target square and "edge"
- is its side.
-
- After the display is drawn you will hear a SysBeep. You
- may interrupt a partially completed display by clicking the
- mouse or pressing any key. You may not see any immediate
- effect, but the drawing will soon terminate with a double
- SysBeep at the end of the current inner loop.
-
- You may print the completed display by pressing "p".
-
- Return to the shell with the close box.
-
-
- Popcorn -6, -6, 12 - an overall view of the 12 unit square about
- the origin.
-
- Popcorn -3, -3, 6 - the central portion of the above. This is about
- the level of magnification of the illustration
- in Scientific American.
-
- Popcorn -2.5, -2.5, 2 - enlargements of a single "kernel".
- Popcorn -2, -2, 1
-
- */
-
- #include <Types.h>
- #include <Windows.h>
- #include <Memory.h>
- #include <Printing.h>
- #include <Fonts.h>
- #include <Resources.h>
- #include <OSUtils.h>
- #include <Math.h>
- #include <StdLib.h>
-
- #define h 0.05
-
- #define windowTop 40
- #define windowLeft 4
- #define windowEdge 200
- #define windowTitle "\pPopcorn"
-
- #define nil 0L
-
-
-
- /**** globals ****/
-
- WindowPtr display;
- Boolean alreadyDrawn;
- BitMap offScreen;
-
- extended top, left, edge;
- extended x0, y0;
- extended increment, scale;
-
-
- void plot (extended x, extended y)
- {
- short xi, yi;
-
- xi = rint(x);
- yi = rint(y);
-
- MoveTo (xi, yi);
- Line (0,0);
- }
-
-
- void drawContents(WindowPtr w)
- {
- short j, k, n;
- extended x, y, xx, yy;
- EventRecord evt;
-
-
- EraseRect(&(w->portRect));
-
- if ( alreadyDrawn )
- CopyBits (&offScreen, &(display->portBits),
- &(offScreen.bounds), &(offScreen.bounds),
- srcCopy, nil);
-
- else
- {
- while ( GetNextEvent(mDownMask + keyDownMask, &evt) )
- {}; /* dump event queue */
-
- PenNormal();
- for ( j = 1; j <= 50; ++j )
- {
- if ( EventAvail(mDownMask + keyDownMask, &evt) )
- break;
- for ( k = 1; k <= 50; ++k )
- {
- x = left + (increment * j);
- y = top + (increment * k);
-
- for ( n = 1; n <= 50; ++n )
- {
- xx = x - h * sin(y + tan(3 * y));
- yy = y - h * sin(x + tan(3 * x));
- x = xx;
- y = yy;
-
- plot (scale * x + x0, scale * y + y0);
- }
- }
- }
- alreadyDrawn = true;
- CopyBits (&(display->portBits), &offScreen,
- &(offScreen.bounds), &(offScreen.bounds),
- srcCopy, nil);
- SysBeep(1);
- }
- }
-
-
- /**** generic tool stuff ****/
-
-
- void doUpdate(WindowPtr w)
- {
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(w);
- ClipRect(&(w->portRect));
- BeginUpdate(w);
- drawContents(w);
- EndUpdate(w);
- SetPort(savePort);
- }
-
-
- void makeOffScreen() /* set up offscreen bitmap to store image */
- {
- Size sizeOfOff;
- short offRowBytes;
-
- offRowBytes = (((windowEdge - 1) / 16) + 1) * 2;
- sizeOfOff = windowEdge * offRowBytes;
-
- offScreen.baseAddr = (QDPtr) NewPtr(sizeOfOff);
- offScreen.rowBytes = offRowBytes;
- SetRect(&(offScreen.bounds), 0, 0, windowEdge, windowEdge);
- }
-
-
- void makeWindow()
- {
- Rect bounds;
-
- SetRect(&bounds, windowLeft, windowTop, windowLeft + windowEdge, windowTop + windowEdge);
- display = NewWindow(nil, &bounds, windowTitle, true, noGrowDocProc, (WindowPtr) -1, true, 0L);
- }
-
-
- void printWindow()
- {
- TPPrPort pport;
- THPrint hPrint;
- TPrStatus PrStatus;
- GrafPtr oldPort;
- Boolean notCancelled = true;
- Boolean drop;
-
- GetPort (&oldPort);
- PrOpen();
-
- SetFractEnable(true);
- SetFScaleDisable(true);
-
- hPrint = (THPrint) NewHandle(sizeof(TPrint));
- if (ResError())
- {
- printf ("Printing Error %d\n", ResError());
- SysBeep(1);
- PrClose();
- return;
- }
-
- drop = PrValidate(hPrint);
- notCancelled = PrJobDialog (hPrint);
-
- if (notCancelled)
- {
- pport = PrOpenDoc(hPrint, nil, nil);
- if ( PrError() == noErr )
- {
- PrOpenPage(pport, nil);
- if (PrError()==noErr)
- CopyBits (&offScreen, &(pport->gPort.portBits),
- &(offScreen.bounds), &(offScreen.bounds),
- srcCopy, nil);
- PrClosePage(pport);
- }
- PrCloseDoc(pport);
- }
- if ( ((**hPrint).prJob.bJDocLoop == bSpoolLoop)
- && (PrError() == noErr) )
- PrPicFile (hPrint, nil, nil, nil, &PrStatus);
-
- SetFractEnable(false);
- SetFScaleDisable(false);
-
- PrClose();
-
- SetPort (oldPort);
- }
-
-
- void mainLoop()
- {
- Boolean done = false;
- EventRecord theEvent;
- WindowPtr whichWindow;
- short part;
-
- while ( !done )
- {
- if ( GetNextEvent(everyEvent, &theEvent) )
- {
- switch ( theEvent.what )
- {
- case updateEvt:
- doUpdate(display);
- break;
-
- case mouseDown:
- part = FindWindow(theEvent.where, &whichWindow);
- if ( (whichWindow == display) && (part == inGoAway) )
- done = true;
- else
- SysBeep(1);
- break;
-
- case keyDown:
- if ( 'p' == (theEvent.message & charCodeMask) )
- printWindow();
- else
- SysBeep(1);
- break;
- }
- }
- }
- }
-
-
- void cleanUp()
- {
- DisposeWindow(display);
- DisposPtr((Ptr) offScreen.baseAddr);
- }
-
-
- int main (
- int argc, /* number of arguments */
- char *argv[], /* pointer to array of argument strings */
- char *envp[]) /* pointer to array of variable definitions */
- {
- #pragma unused (envp)
-
- InitGraf((Ptr) &qd.thePort);
- SetFScaleDisable(true);
- InitCursor();
-
- if ( argc != 4 )
- {
- printf ("### Wrong Number of Parameters ###\n");
- return 2;
- }
-
- top = atof(argv[1]);
- left = atof(argv[2]);
- edge = atof(argv[3]);
-
- increment = edge / 50;
- scale = windowEdge / edge;
- x0 = (windowEdge / 2) - ((left + (edge / 2)) * scale);
- y0 = (windowEdge / 2) - ((top + (edge / 2)) * scale);
-
- alreadyDrawn = false;
-
- makeOffScreen();
- makeWindow();
- mainLoop();
- cleanUp();
-
- return 0;
- }
-